from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from django.contrib.auth import login
from django.db import DatabaseError
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
from celery_tasks.email.tasks import send_verify_email
from apps.qqlogin.models import OAuthQQUser
from apps.users.models import User
from apps.users.utils import generate_verify_email_url
from shopping_mall.utils.secret import SecretOauth
import re
import json


# QQ登陆，返回QQ登陆页面
class QQURLView(View):
    def get(self, request):
        # 1：登陆成功后跳转的网页
        next = request.GET.get("next")
        # 2：创建QQ登陆对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)
        # 3:拿到QQ登陆的地址
        login_url = oauth.get_qq_url()

        return JsonResponse({
            "code": 0,
            "errmsg": "ok",
            "login_url": login_url
        })


# QQ登陆模块
class QQUserView(View):

    def get(self, request):
        # 1：拿到code
        code = request.GET.get("code")

        if not code:
            return JsonResponse({
                "code": 400,
                "errmsg": "缺失参数"
            })
        # 2:创建QQ对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)
        # 3:获取penid
        try:
            access_token = oauth.get_access_token(code)
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            return JsonResponse({
                "code": 0,
                "errmsg": "无法获取access_token"
            })
        else:
            try:
                oauth_qq = OAuthQQUser.objects.get(openid=openid)
            except Exception as e:
                # 用户没有绑定美多商城用户,使用加密类加密用户的openid,返回给用户，前端会让顾客填写信息，然后再带着这个openid返回
                access_token = SecretOauth().dumps({'openid': openid})
                # 注意: 这里一定不能返回 0 的状态码. 否则不能进行绑定页面
                return JsonResponse({'code': 300, 'errmsg': 'ok', 'access_token': access_token})


            else:  # 4.1: 数据库中查询到了用户
                user = oauth_qq.user

                # 状态保持与设置cookie
                login(request, user)

                response = JsonResponse({
                    "code": 0,
                    "errmsg": "ok"
                })
                response.set_cookie("username", user.username, max_age=3600 * 24 * 14)

                return response

    def post(self, request):
        """美多商城用户绑定到openid"""

        # 1.接收参数
        data_dict = json.loads(request.body.decode())
        mobile = data_dict.get('mobile')
        password = data_dict.get('password')
        sms_code_client = data_dict.get('sms_code')
        access_token = data_dict.get('access_token')

            # 调用我们自定义的函数, 检验传入的 access_token 是否正确:
        # 错误提示放在 sms_code_errmsg 位置
        openid = SecretOauth().loads(access_token).get('openid')
        if not openid:
            return JsonResponse({'code': 400,
                                 'errmsg': '缺少openid'})
        # 4.保存注册数据
        try:
            user = User.objects.get(mobile=mobile)
        except Exception as e:
            # 用户不存在,新建用户
            user = User.objects.create_user(username=mobile,
                                            password=password,
                                            mobile=mobile)
        else:
            # 如果用户存在，检查用户密码
            if not user.check_password(password):
                return JsonResponse({'code': 400,
                                     'errmsg': '输入的密码不正确'})
        # 5.将用户绑定 openid
        try:
            OAuthQQUser.objects.create(openid=openid,
                                       user=user)
        except DatabaseError:
            return JsonResponse({'code': 400,
                                 'errmsg': '往数据库添加数据出错'})
        # 6.实现状态保持
        login(request, user)

        # 7.创建响应对象:
        response = JsonResponse({'code': 0,
                                 'errmsg': 'ok'})

        # 8.登录时用户名写入到 cookie，有效期14天
        response.set_cookie('username',
                            user.username,
                            max_age=3600 * 24 * 14)

        # 9.响应
        return response

# 邮箱写入数据库
class EmailView(View):
    def put(self, request):
        data = json.loads(request.body.decode())
        email = data.get("email")
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            return JsonResponse({
                "code": 400,
                "errmsg": "邮箱数据库写入失败"
            })


        verify_url = generate_verify_email_url(request)
        # 发送验证链接:
        send_verify_email.delay(email, verify_url)
        return JsonResponse({
            "code": 0,
            "errmsg": "ok"
        })

# 邮箱验证成功后修改数据库字段
class VerifyEmailView(View):
    def put(self, request):
        # - 1.接收 token
        token = request.GET.get('token')

        if not token:
            return JsonResponse({'code': 400, 'errmsg': 'token缺少'})

        # - 2.解密
        data_dict = SecretOauth().loads(token)

        # - 4.去数据库对比 user_id,email
        try:
            user = User.objects.get(pk=data_dict.get('user_id'), email=data_dict.get('email'))
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '参数有误!'})

        # - 5.修改激活状态
        try:
            user.email_active = True
            user.save()
        except Exception as e:
            return JsonResponse({'code': 0, 'errmsg': '激活失败!'})

        return JsonResponse({'code': 0, 'errmsg': '激活成功!'})


